/**
 * API client for grep.app integration
 */

import axios, { AxiosInstance, AxiosError } from 'axios';
import { SearchParams, GrepAPIParams, SearchResponse, GrepAPIError, GrepAPITimeoutError, GrepAPIRateLimitError } from '../types.js';

export class GrepAPIClient {
  private client: AxiosInstance;

  constructor() {
    this.client = axios.create({
      baseURL: 'https://grep.app/api',
      timeout: 30000, // 30 seconds timeout
      headers: {
        'User-Agent': 'grep-mcp-ts/1.0.0'
      }
    });
  }

  /**
   * Search GitHub repositories using grep.app API
   */
  async search(params: SearchParams): Promise<SearchResponse> {
    // Convert user-friendly params to API params
    const apiParams: GrepAPIParams = {
      q: params.query
    };
    
    if (params.language) apiParams['f.lang'] = params.language;
    if (params.repo) apiParams['f.repo'] = params.repo;
    if (params.path) apiParams['f.path'] = params.path;

    try {
      const response = await this.client.get<SearchResponse>('/search', { params: apiParams });
      return response.data;
    } catch (error) {
      if (axios.isAxiosError(error)) {
        const axiosError = error as AxiosError;
        
        if (axiosError.code === 'ECONNABORTED' || axiosError.message.includes('timeout')) {
          throw new GrepAPITimeoutError('Request to grep.app API timed out');
        }
        
        if (axiosError.response?.status === 429) {
          throw new GrepAPIRateLimitError('Rate limit exceeded. Please wait before making another request.');
        }
        
        if (axiosError.response?.status === 404) {
          // Return empty response for 404 errors
          return {
            facets: {
              count: 0,
              lang: { buckets: [] },
              repo: { buckets: [] }
            },
            hits: {
              hits: []
            }
          };
        }
        
        throw new GrepAPIError(`API request failed with status ${axiosError.response?.status || 'unknown'}: ${axiosError.message}`);
      }
      
      throw new GrepAPIError(`Unexpected error occurred: ${error instanceof Error ? error.message : String(error)}`);
    }
  }
}